#ifndef WIDGET_H
#define WIDGET_H

#include <QFinalState>
#include <QLineEdit>
#include <QStateMachine>
#include <QWidget>
#include "dialog_login.h"
#include "dialog_configsystermparas.h"
#include "dialog_configworkgroupparas.h"
#include "dialog_selectworkgroup.h"
#include "dialog_lightcontrol.h"
#include "dialog_camadjust.h"
#include "dialog_inputcode.h"
#include "dialog_codescanstart.h"
#include "serialporthandler.h"
#include "modbusserialtest.h"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    uint16_t ModbusCRC16(QByteArray senddata);// CRC校验

    void initGroupData();// 初始化用户组数据
    void InitEntIPPort();   // 初始化IP端口
    QString ensureThreeDigits(const QString &input);    //返回三位整形数字符串
public slots:

    void sendTopRoSideLightAdjustData(QString dat);
    void getTopAdjustData(QByteArray dat);
    void do_setCurrentGroupSize(QString groupSize);

    void do_setCurrentGroupName(QString groupName);

    void do_updateShiftOnAStatusStatusCode(uint8_t state);
    void do_checkCode(QString code);
    void sendBottomLightAdjustData(QString dat);
    void do_setCurrentGroupData(const QMap<QString, QString> map_group);
    void getSideAdjustData(QByteArray dat);

    void GetCurrentGroupData();

    void do_checkPortConnection();
signals:
    void sendLightSData(const QString sData);
    void sendCurrentWorkGroupData(const QMap<QString, QString> map);
private:
    Ui::Widget *ui;

    // 串口
    SerialPortHandler top_side_light_sport,top_cam_focus_sport,bottom_light_sport,side_cam_focus_sport;
    ModbusSerialTest plc_port; // plc端口

    bool m_portGlobalFlag = false;

    bool device_switch_flag = false; // 设备启停标志位
    bool plc_state_flag = false;    // plc连接标志位

    QStringList currentSteps;    // 当前状态

    bool m_switchHandOperFlag = false;    // 手动操作标志位

    QMap<QString, QString> map_currentGroup;    // 当前组字典

    uint16_t plcStateBit = 0;   // plc状态位

    bool m_nextStateFlag = true;    // 下一个状态标志位

    bool m_getHttpCsvFlag = true;
    uint8_t m_getHttpCsvTime_S = 3; // 3秒钟获取一次

    HttpRequest *m_http = nullptr; // http

    bool m_productCodeFlag = false; // 产品码标志位

    QString m_productUniqueCode;    // 产品码

    uint16_t m_topPhotoRequest; // PLC顶部拍照请求

    uint16_t m_ABCD_PhotoRequest; // PLC侧边ABCD面拍照请求

    uint16_t m_bottomPhotoRequest; // PLC底部面拍照请求

    bool m_topPhotoFinishFlag = false; // 顶部拍照完成标志位
    bool m_AsidePhotoFinishFlag = false; // A面拍照完成标志位
    bool m_BsidePhotoFinishFlag = false; // B面拍照完成标志位
    bool m_CsidePhotoFinishFlag = false; // C面拍照完成标志位
    bool m_DsidePhotoFinishFlag = false; // D面拍照完成标志位
    bool m_bottomPhotoFinishFlag = false; // 顶部拍照完成标志位


    QString m_productCode;  // 产品码
//    QTimer *m_portConnection = nullptr;

///////////////////////////////////////////////////////////////////////////////////////////////////////
//状态机
///////////////////////////////////////////////////////////////////////////////////////////////////////

public:
    void initMachineConnectEnteredExited();

    // 初始化状态机，完成信号连接槽
    void initMachineConnectFinish();

    void initIdleStateConnectEnteredExited();

    void initForScanStateConnectEnteredExited();

    void initCameraStateConnectEnteredExited();

    void initResetStateConnectEnteredExited();

    void initIdleState();

    void MyStateMachineInit();

    void InitMachine();

    void deleteStateMachine();

    QMap<QString, QVariant> parseCsvToMap(const QString &csvString);
signals:
    void toNextState(); // 跳转到下一个状态
    void toStateWork();     // 跳转某一个状态的工作函数

    void resetIdleState(); // 复位到空闲状态
    void resetForScanState(); // 复位到等待扫描状态
    void pauseState(); // 暂停状态

    void plcChainWidthCurrentSize(const QString &ChainWidthCurrentSize);

private slots:
    void showLoginDialog();
    void on_btn_selectWorkGroup_clicked();

    void on_btn_configWorkGroup_clicked();

    void on_btn_systemConfig_clicked();

    void on_btn_switchHandOper_clicked();

//    void on_btn_InputCode_clicked();

    void on_btn_codeScanStart_clicked();

    void on_btn_operPause_clicked();

    void on_on_resetGlobal_clicked();

    void on_btn_LightSourceControl_clicked();

    void on_btn_camAdjust_clicked();

    void on_btn_switch_clicked();

    void do_updatelatestStatusCode(const uint16_t statusCode);
    void on_btn_shiftOnA_clicked();
    void on_btn_Stop_clicked();

public slots:
    void do_idleState_To_ForScanState();
    void do_forScanState_To_CameraState();
    void do_cameraState_To_ResetStartedState();
    void do_resetStartedState_To_idleState();


    void do_cameraSelfTest_To_lightSelfTest();
    void do_lightSelfTest_To_CameraState();
    void do_lightSelfTest_To_cameraConnSelfTest();
    void do_cameraConnSelfTest_To_plcSelfTest();
    void do_plcSelfTest_To_industrialCtrlNetSelfTest();
    void do_industrialCtrlNetSelfTest_To_industrialCtrlNetSelfTest();
    void do_secretMachineSelfTest_To_finalSelfTest();


    void do_waitingForScanState_To_writBbufferState();
    void do_writBbufferState_To_workpieceArrives1();
    void do_workpieceArrives1_To_ForScanFinal();


    void do_photoTop_To_photoFaceA();
    void do_photoFaceA_To_photoFaceB();
    void do_photoFaceB_To_photoFaceC();
    void do_photoFaceC_To_photoFaceD();
    void do_photoFaceD_To_photoBottom();
    void do_photoBottom_To_cameraFinal();


    void do_cuttingSensorStatus_To_SingleJobResetComplete();
    void do_SingleJobResetComplete_To_resetStatus();
    void do_resetStatus_To_resetFinal();

    void onTimeoutStateMachine();
    void do_closeSerialPort();
    void do_initSerialPort();
    void getScanStartProductCode(const QString &productCode);
    void do_compareWorkGroup(uint8_t x);
public:
    void do_Work_cameraSelfTest();
    void do_Work_lightSelfTest();
    void do_Work_cameraConnSelfTest();
    void do_Work_plcSelfTest();
    void do_Work_industrialCtrlNetSelfTest();
    void do_Work_secretMachineSelfTest();
    void do_Work_finalSelfTest();
    void do_Work_waitingForScanState();
    void do_Work_writBbufferState();
    void do_Work_workpieceArrives1();
    void do_Work_ForScanFinal();
    void do_Work_photoTop();
    void do_Work_photoFaceA();
    void do_Work_photoFaceB();
    void do_Work_photoFaceC();
    void do_Work_photoFaceD();
    void do_Work_photoBottom();
    void do_Work_cameraFinal();
    void do_Work_cuttingSensorStatus();
    void do_Work_SingleJobResetComplete();
    void do_Work_resetStatus();
    void do_Work_resetFinal();




    QMap<QString, QString> getCsvPhotoJson(const QString &productUniqueCode, const QString &cameraCode, const QString &cameraStatus, const QString &takePhotoNum = "1");
    QByteArray intToByteArray(int value);
    QByteArray formSetAngleData(int16_t angle);
    void sendSideFormSetData(int16_t angle);
    void sendTopFormSetData(int16_t angle);
    bool sendPhotoFinishPost(QMap<QString, QString> postData);
    void updatePortConnectStatus();
    QStringList readStepsFromFile(const QString &fileName);
    void updatePlcGroupData(const QString &groupName);
    void setTextColor(QLineEdit *le, const QString &text, const QColor &color);
private:
    QTimer *StateMachineTimer = nullptr;

    uint8_t m_timeCountFinishVal = 5;   // 旋转延时时间
    bool m_checkPortFlag = false; // 端口连接标志位
    uint8_t m_checkPortTime = 10;  // 端口状态检测更新时间
//    bool m_checkPlcFlag = false; // plc连接标志位
    bool m_checkHttpFlag = false; // http连接标志位

    // 创建状态机
    QStateMachine *machine = nullptr;

    // 创建状态
    QState *idleState = nullptr;// 设备状态自检，跳转到等待扫描状态
    QState *forScanState = nullptr;// 扫描成功或点击启动按键，倍速链启动，写缓冲区，到达工位一后，跳转拍摄状态
    QState * cameraState = nullptr; // 拍摄状态，依次进行顶端、A面、B面、C面、D面、底部拍摄，所有拍摄完毕后，跳转
    QState *resetStartedState = nullptr;// 产品下料，下料完毕，模组复位后，跳转等待扫描
    QState *stoppedState = nullptr; // 暂停状态


    QState *cameraSelfTest = nullptr; // 相机自检
    QState *lightSelfTest = nullptr; // 光源自检
    QState *cameraConnSelfTest = nullptr; // 镜头自检
    QState *plcSelfTest = nullptr; // PLC自检
    QState *industrialCtrlNetSelfTest = nullptr; // 工控网自检
    QState *secretMachineSelfTest = nullptr; // 国密机自检
    QFinalState *finalSelfTest = nullptr;// 完成系统自检


    QState *waitingForScanState = nullptr;
    QState *writBbufferState = nullptr;// 写缓冲区
    QState *workpieceArrives1 = nullptr; // 工件到达工位一
    QFinalState *ForScanFinal = nullptr;// 上料完成


    QState *photoTop = nullptr;   // 拍顶部
    QState *photoFaceA = nullptr; // 拍A面
    QState *photoFaceB = nullptr; // 拍B面
    QState *photoFaceC = nullptr; // 拍C面
    QState *photoFaceD = nullptr;// 拍D面
    QState *photoBottom = nullptr;// 拍底面
    QFinalState *cameraFinal = nullptr;// 所有拍照完成


    QState *cuttingSensorStatus = nullptr;// 产品下料
    QState *SingleJobResetComplete = nullptr;// 单一工件复位
    QState *resetStatus = nullptr;       // 复位状态
    QFinalState *resetFinal = nullptr;// 下料完成

};
#endif // WIDGET_H
